<?php
namespace App\Admin\Controllers\SalesReportLT;

use App\Logic\MonthlyReportLT\CheckLogisticsAvgPrice;
use App\Models\Basics\SysPlat;
use App\Models\CustomerDelivery\CustomerDelivery;
use App\Models\MonthlyReportLT\Cost\LogisticsBasics;
use App\Models\MonthlyReportLT\Cost\LogisticsBasicsCancel;
use App\Models\MonthlyReportLT\Payment\PaymentCancelOrderDelivery;
use App\Models\MonthlyReportLT\Payment\PaymentOrder;
use App\Models\MonthlyReportLT\Tmp\TmpReFee;
use App\Models\MonthlyReportLT\Tmp\TmpSales;
use App\Models\OverSeasIn\Delivery as OSDelivery;
use App\Models\Product\ProductSku;
use Encore\Admin\Controllers\AdminController;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\StreamedResponse;

class ManualController extends AdminController{

    protected $title = '乐天月报核算说明';

    protected function grid()
    {
        return view('sales-report.payment-manual-lt.index');
    }
    //排查漏上传的SKU
    public function skuDownload(){
        $head = ['问题字段','问题描述','源文件','时间'];
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="排查出的乐天未上传的产品.csv"',
        ]);
        $query = DB::table('lt_mr_parse_miss');
        $response->setCallback(function () use ($head, $query) {
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $query->orderBy('id')->chunk(100, function ($re) use ($fp){
                $data = self::_getSkuData($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getSkuData($re)
    {
        foreach ($re as $row){
            $temp = [];
            $temp['field'] = $row->field;
            $temp['desc'] = $row->desc;
            $temp['sour'] = array_key_exists($row->sour,self::$_file) ? self::$_file[$row->sour] : $row->sour;
            $temp['created_at'] = $row->created_at;
            yield $temp;
        }
    }

    private static $_file = [
        'sa' => '销售明细',
        're' => '退货明细',
        'th' => '第三方发货费',
        'ads' => '广告费',
    ];

    //匹配销售明细SKU（更新SKU ID）
    public function salesSkuDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="匹配销售明细SKU_ID异常的乐天订单.csv"',
        ]);
        $response->setCallback(function (){
            $head = ['日期', '订单号', 'SKU', '销售额', '销量'];
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            TmpSales::query()->where('psku_id',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getSalesSkuData($re);
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getSalesSkuData($re): \Generator
    {
        foreach ($re as $row){
            $temp = [
                $row->report_date,
                $row->order_id,
                $row->sku,
                $row->product_sales,
                $row->quantity
            ];
            yield $temp;
        }
    }

    //匹配退货明细SKU（更新SKU ID）
    public function reFeeSkuDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="匹配退货明细SKU_ID异常的乐天订单.csv"',
        ]);
        $response->setCallback(function (){
            $head = ['日期', '订单号', 'SKU', '退货额', '退货量'];
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            TmpReFee::query()->where('psku_id',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getReFeeSkuData($re);
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getReFeeSkuData($re): \Generator
    {
        foreach ($re as $row){
            $temp = [
                $row->report_date,
                $row->order_id,
                $row->sku,
                $row->product_sales,
                $row->quantity
            ];
            yield $temp;
        }
    }

    //匹配发货明细SKU
    public function deliverySkuDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="匹配发货单异常的乐天订单.csv"',
        ]);
        $response->setCallback(function (){
            $head = ['日期', '订单号', 'SKU', 'SKU ID', '销售额', '销量'];
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            TmpSales::query()->where('status','<>',1)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getDeliverySkuData($re);
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getDeliverySkuData($re): \Generator
    {
        foreach ($re as $row){
            $temp = [
                $row->report_date,
                $row->order_id,
                $row->sku,
                $row->psku_id,
                $row->product_sales,
                $row->quantity
            ];
            yield $temp;
        }
    }

    //核算产品平均物流成本
    public function logisticsAvgPriceDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="乐天订单运费平均价格核算状态.csv"',
        ]);
        $response->setCallback(function (){
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, ['类型', '订单号', '说明', 'SKU']);
            //OSDelivery
            OSDelivery::query()
                ->where('plat_id',SysPlat::PLAT_RAKUTEN)
                ->where('delivery_type',OSDelivery::OS_DELIVERY_DROPSHIPPING)
                ->where('logistics_check_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsAvgPriceData($re,'海外仓代发-入仓');
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            //CustomerDelivery
            CustomerDelivery::query()
                ->where('plat_id',SysPlat::PLAT_RAKUTEN)
                ->where('delivery_type',CustomerDelivery::DELIVERY_TYPE_CN)
                ->where('logistics_check_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsAvgPriceData($re,'客户订单发货出仓');
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            //CustomerDelivery-出仓
            CustomerDelivery::query()
                ->where('plat_id',SysPlat::PLAT_RAKUTEN)
                ->where('delivery_type',CustomerDelivery::DELIVERY_TYPE_ABROAD)
                ->where('logistics_check_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsAvgPriceData($re,'海外仓代发-出仓');
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getLogisticsAvgPriceData($re,$type): \Generator
    {
        foreach ($re as $row){
            $temp = [
                $type,
                $row->delivery_no,
                CheckLogisticsAvgPrice::$_logisticsCheckStatus[$row->logistics_check_status],
                '',
            ];
            yield $temp;
            foreach ($row->detail as $item){
                $temp = [
                    '',
                    '',
                    '',
                    ProductSku::getValueById($item->psku_id,'psku_code'),
                ];
                yield $temp;
            }
        }
    }
    //统计国内直发订单运费
    public function logisticsOrderCNDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="乐天订单国内直发订单运费统计状态.csv"',
        ]);
        $response->setCallback(function (){
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, ['日期', '订单号', 'SKU ID', 'SKU','国内直发数量']);
            $date = date('Y-m-01',strtotime('midnight first day of -1 month'));
            PaymentOrder::query()
                ->where('report_date',$date)
                ->where('cn_quantity','>',0)
                ->where('check_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsOrderCNData($re);
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getLogisticsOrderCNData($re): \Generator
    {
        $sku = [];
        foreach ($re as $row){
            if(!array_key_exists($row->psku_id,$sku)){
                $sku[$row->psku_id] = ProductSku::getValueById($row->psku_id,'psku_code');
            }
            $temp = [
                $row->report_date,
                $row->order_id,
                $row->psku_id,
                $sku[$row->psku_id],
                $row->quantity
            ];
            yield $temp;
        }
    }
    //统计海外仓出仓订单运费
    public function logisticsOrderOSOutDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="乐天订单海外仓出仓订单运费统计状态.csv"',
        ]);
        $response->setCallback(function (){
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, ['日期', '订单号', 'SKU ID', 'SKU','海外仓出仓数量']);
            $date = date('Y-m-01',strtotime('midnight first day of -1 month'));
            PaymentOrder::query()
                ->where('report_date',$date)
                ->where('os_quantity','>',0)
                ->where('check_os_out_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsOrderOSOutData($re);
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getLogisticsOrderOSOutData($re): \Generator
    {
        $sku = [];
        foreach ($re as $row){
            if(!array_key_exists($row->psku_id,$sku)){
                $sku[$row->psku_id] = ProductSku::getValueById($row->psku_id,'psku_code');
            }
            $temp = [
                $row->report_date,
                $row->order_id,
                $row->psku_id,
                $sku[$row->psku_id],
                $row->quantity
            ];
            yield $temp;
        }
    }
    //统计国内直发已取消订单的运费
    public function logisticsOrderCNCancelDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="乐天订单国内直发已取消订单运费统计状态.csv"',
        ]);
        $response->setCallback(function (){
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, ['日期', '订单号', 'SKU ID', 'SKU','国内直发数量']);
            $date = date('Y-m-01',strtotime('midnight first day of -1 month'));
            PaymentCancelOrderDelivery::query()
                ->where('report_date',$date)
                ->where('cn_quantity','>',0)
                ->where('check_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsOrderCNCancelData($re);
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getLogisticsOrderCNCancelData($re): \Generator
    {
        $sku = [];
        foreach ($re as $row){
            if(!array_key_exists($row->psku_id,$sku)){
                $sku[$row->psku_id] = ProductSku::getValueById($row->psku_id,'psku_code');
            }
            $temp = [
                $row->report_date,
                $row->order_id,
                $row->psku_id,
                $sku[$row->psku_id],
                $row->quantity
            ];
            yield $temp;
        }
    }

    //统计海外仓代发出仓已取消订单的运费
    public function logisticsOrderOSOutCancelDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="乐天订单海外仓代发出仓已取消订单运费统计状态.csv"',
        ]);
        $response->setCallback(function (){
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, ['日期', '订单号', 'SKU ID', 'SKU','海外仓代发出仓数量']);
            $date = date('Y-m-01',strtotime('midnight first day of -1 month'));
            PaymentCancelOrderDelivery::query()
                ->where('report_date',$date)
                ->where('os_quantity','>',0)
                ->where('check_os_out_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsOrderOSOutCancelData($re);
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getLogisticsOrderOSOutCancelData($re): \Generator
    {
        $sku = [];
        foreach ($re as $row){
            if(!array_key_exists($row->psku_id,$sku)){
                $sku[$row->psku_id] = ProductSku::getValueById($row->psku_id,'psku_code');
            }
            $temp = [
                $row->report_date,
                $row->order_id,
                $row->psku_id,
                $sku[$row->psku_id],
                $row->quantity
            ];
            yield $temp;
        }
    }

    //海外仓代发纳入运费系统
    public function logisticsBalanceDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="乐天未纳入运费系统的订单.csv"',
        ]);
        $response->setCallback(function (){
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
//            fputcsv($fp, ['类型', '订单号']);
            fputcsv($fp, ['订单号']);
            //OSDelivery
            OSDelivery::query()
                ->where('plat_id',SysPlat::PLAT_RAKUTEN)
                ->where('status','>=',6)//已发货或已入海外仓中转仓
                ->where('logistics_status',2)//运费已更新
                ->where('logistics_fee_status',0)//未纳入统计
                ->where('logistics_check_status',0)//运费核算状态正常
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsBalanceData($re);
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getLogisticsBalanceData($re): \Generator
    {
        foreach ($re as $row){
            $temp = [
//                '海外仓代发-入仓',
                $row->delivery_no,
            ];
            yield $temp;
        }
    }

    //核算销售产品运费
    public function logisticsBasicsDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="乐天物流成本.csv"',
        ]);
        $date = date('Y-m-01',strtotime('midnight first day of -1 month'));
        $_date = date('Y-m-01',strtotime('midnight first day of -3 month'));
        $query = LogisticsBasics::query()->where('b_date','>=',$_date)->where('b_date','<=',$date);
        $response->setCallback(function () use ($query) {
            $head = ['日期', 'SKU ID', 'SKU', '销量', '总成本'];
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $query->orderBy('id')->chunk(100, function ($re) use ($fp){
                $data = self::_getLogisticsBasicsData($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getLogisticsBasicsData($re): \Generator
    {
        $sku = [];
        foreach ($re as $row){
            if(!array_key_exists($row->psku_id,$sku)){
                $sku[$row->psku_id] = ProductSku::getValueById($row->psku_id,'psku_code');
            }
            $temp = [
                $row->b_date,
                $row->psku_id,
                $sku[$row->psku_id],
                $row->quantity,
                round($row->os_fei+ $row->fba_fei + $row->cn_fei,3)
            ];
            yield $temp;
        }
    }

    //核算取消订单的产品运费
    public function logisticsBasicsCancelDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="乐天取消订单SKU物流成本.csv"',
        ]);
        $date = date('Y-m-01',strtotime('midnight first day of -1 month'));
        $_date = date('Y-m-01',strtotime('midnight first day of -3 month'));
        $query = LogisticsBasicsCancel::query()->where('b_date','>=',$_date)->where('b_date','<=',$date);
        $response->setCallback(function () use ($query) {
            $head = ['日期', 'SKU ID', 'SKU', '销量', '总成本'];
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $query->orderBy('id')->chunk(100, function ($re) use ($fp){
                $data = self::_getLogisticsBasicsCancelData($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getLogisticsBasicsCancelData($re): \Generator
    {
        $sku = [];
        foreach ($re as $row){
            if(!array_key_exists($row->psku_id,$sku)){
                $sku[$row->psku_id] = ProductSku::getValueById($row->psku_id,'psku_code');
            }
            $temp = [
                $row->b_date,
                $row->psku_id,
                $sku[$row->psku_id],
                $row->quantity,
                round($row->os_fei+ $row->fba_fei + $row->cn_fei,3)
            ];
            yield $temp;
        }
    }
}
